package com.fesine.crm.service.impl;

import com.fesine.commons.util.DateUtils;
import com.fesine.crm.exception.CrmException;
import com.fesine.crm.po.*;
import com.fesine.crm.service.*;
import com.fesine.crm.util.SystemUtils;
import com.fesine.service.impl.BaseServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @description: 类描述
 * @author: Fesine
 * @createTime:2017/10/23
 * @update:修改内容
 * @author: Fesine
 * @updateTime:2017/10/23
 */
@Service
public class EventListServiceImpl extends BaseServiceImpl<EventListPo> implements EventListService {

    private static final Logger logger = LoggerFactory.getLogger(EventListServiceImpl.class);


    @Autowired
    private ErrorListService errService;

    @Autowired
    private NameCompareService nameService;

    @Autowired
    private EmployeeInfoService empService;

    @Autowired
    private AttendanceInfoService attService;




    /**
     * 添加考勤表数据到事件表中
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void analyseData() {
        FileInfoPo filePo = new FileInfoPo();
        filePo.setExeStatus(0);
        List<FileInfoPo> list = daoService.selectList(filePo);
        if (CollectionUtils.isEmpty(list)) {
            throw new CrmException(404,"没有找到需要分析数据!");
        }
        AttendanceInfoPo attPo = new AttendanceInfoPo();
        attPo.setRemark2("0");
        List<AttendanceInfoPo> attList = attService.listAll(attPo);
        EventListPo po;
        EmployeeInfoPo empPo;
        NameComparePo namePo = new NameComparePo();
        List<NameComparePo> nameList = nameService.listAll(namePo);
        Map<String, NameComparePo> nameMap = new HashMap<>();
        Map<String, String> pacteraMap = new HashMap<>();
        for (NameComparePo comparePo : nameList) {
            nameMap.put(comparePo.getAttName(), comparePo);
        }
        String name;
        for (AttendanceInfoPo infoPo : attList) {
            if (nameMap.get(infoPo.getName()) != null) {
                name = nameMap.get(infoPo.getName()).getEmpName();
            } else {
                name = infoPo.getName();
            }
            String pacteraNo = pacteraMap.get(name);
            if (null == pacteraNo) {
                empPo = new EmployeeInfoPo();
                empPo.setName(name);
                empPo = empService.get(empPo);
                if (empPo != null) {
                    pacteraNo = empPo.getPacteraNo();
                    pacteraMap.put(name, pacteraNo);
                }
            }
            po = new EventListPo();
            po.setPacteraNo(pacteraNo);
            po.setName(name);
            po.setEventDate(infoPo.getEventTime());
            po.setEventTime(infoPo.getEventTime());
            if (infoPo.getEventType().contains("通过")) {
                po.setStatus(1);
            } else {
                po.setStatus(0);
            }
            po.setWeek(SystemUtils.getWeekDay(infoPo.getEventTime()));
            daoService.insert(po);
        }
        //更新原始考勤数据状态
        AttendanceInfoPo wherePo = new AttendanceInfoPo();
        wherePo.setRemark2("0");
        AttendanceInfoPo setPo = new AttendanceInfoPo();
        setPo.setRemark2("1");
        attService.update(setPo, wherePo);
        //更新文件状态由0-1
        FileInfoPo whereFilePo = new FileInfoPo();
        whereFilePo.setExeStatus(0);
        FileInfoPo setFilePo = new FileInfoPo();
        setFilePo.setExeStatus(1);
        daoService.update(setFilePo, whereFilePo);
    }

    /**
     * 处理工作日所有员工考勤数据
     * @param dateStr
     * @param amDateStr
     * @param pmDateStr
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addErrorList(String dateStr, String amDateStr, String pmDateStr) {
        FileInfoPo filePo = new FileInfoPo();
        filePo.setExeStatus(1);
        filePo.setMonthStr(dateStr);
        filePo = daoService.selectOne(filePo);
        if (filePo == null) {
            throw new CrmException(404, "没有找到需要分析数据!");
        }
        Calendar calendar = Calendar.getInstance();
        try {
            List<EmployeeInfoPo> empList = daoService.selectList(new EmployeeInfoPo());

            for (EmployeeInfoPo empPo : empList) {
                Date amDate = DateUtils.formatString(amDateStr, "HH:mm");
                Date pmDate = DateUtils.formatString(pmDateStr, "HH:mm");
                calendar.setTime(DateUtils.formatString(dateStr, "yyyy-MM"));
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.add(Calendar.MONTH, 1);
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                //当月最后一天
                int maxDate = calendar.get(Calendar.DATE);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                for (int i = 0; i < maxDate; i++) {
                    if (i == 0) {
                        calendar.add(Calendar.DATE, 0);
                    } else {
                        calendar.add(Calendar.DATE, 1);
                    }
                    int weekDay = SystemUtils.getWeekDay(calendar.getTime());
                    String dateTemp = DateUtils.formatDate(calendar.getTime(), "yyyy-MM-dd");
                    if (weekDay == 6 || weekDay == 7) {
                        logger.info("---->当前日期 {} 是周{}，忽略", dateTemp, weekDay);
                        continue;
                    }
                    execErrorData(calendar, empPo, amDate, pmDate);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CrmException(404, "没有找到需要分析数据!");
        }
        //更新为已经处理
        filePo.setExeStatus(2);
        daoService.update(filePo);
    }

    /**
     * 处理指定日期，所有员工考勤数据
     * @param dateStr
     * @param amDateStr
     * @param pmDateStr
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addErrorListByDate(String dateStr, String amDateStr, String pmDateStr) {
        Calendar calendar = Calendar.getInstance();
        try {
            List<EmployeeInfoPo> empList = daoService.selectList(new EmployeeInfoPo());
            for (EmployeeInfoPo empPo : empList) {
                Date amDate = DateUtils.formatString(amDateStr, "HH:mm");
                Date pmDate = DateUtils.formatString(pmDateStr, "HH:mm");
                calendar.setTime(DateUtils.formatString(dateStr,"yyyy-MM-dd"));
                execErrorData(calendar, empPo, amDate, pmDate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 处理指定日期指定员工上班考勤数据
     * @param calendar
     * @param empPo
     * @param amDate
     * @param pmDate
     */
    @Transactional(rollbackFor = Exception.class)
    private void execErrorData(Calendar calendar, EmployeeInfoPo empPo, Date amDate, Date pmDate) {
        String dateTemp = DateUtils.formatDate(calendar.getTime(), "yyyy-MM-dd");
        ErrorListPo errorPoTemp = new ErrorListPo();
        errorPoTemp.setName(empPo.getName());
        errorPoTemp.setPacteraNo(empPo.getPacteraNo());
        errorPoTemp.setErrorDate(calendar.getTime());
        errorPoTemp = daoService.selectOne(errorPoTemp);
        if (errorPoTemp != null) {
            logger.info("{} {} 异常数据已经处理！", empPo.getName(), dateTemp);
            return;
        }
        logger.info("---->当前日期是 {}", dateTemp);
        int weekDay = SystemUtils.getWeekDay(calendar.getTime());
        EventListPo event = new EventListPo();
        //姓名
        event.setName(empPo.getName());
        //查询每一天的考勤记录
        //验证上班打卡
        event.setEventDate(calendar.getTime());
        event.setQueryBeginDate(amDate);
        //打卡成功状态
        event.setStatus(1);
        List<EventListPo> eventList = daoService.selectList("selectListByEventTime", event);
        boolean amFlag = true;
        boolean pmFlag = true;
        boolean addFlag = false;
        Integer errorType = 0;
        String errorMsg = "上班考勤迟到！";
        if (CollectionUtils.isEmpty(eventList)) {
            amFlag = false;
            addFlag = true;
            logger.error("{} {} 周{} 上班考勤迟到！", empPo.getName(), dateTemp, weekDay);
        }
        if(!amFlag){
            //查询打卡失败记录
            event.setStatus(0);
            eventList = daoService.selectList("selectListByEventTime", event);
            if (CollectionUtils.isNotEmpty(eventList)) {
                amFlag = false;
                addFlag = true;
                errorType = 4;
                errorMsg = "上班考勤打卡失败！";
                logger.error("{} {} 周{} 上班考勤打卡失败！", empPo.getName(), dateTemp, weekDay);
            }
        }
        //验证下班打卡
        event.setQueryBeginDate(null);
        event.setStatus(1);
        event.setQueryEndDate(pmDate);
        eventList = daoService.selectList("selectListByEventTime", event);
        if (CollectionUtils.isEmpty(eventList)) {
            pmFlag = false;
            addFlag = true;
            errorType = 1;
            errorMsg = "下班考勤未打卡！";
            logger.error("{} {} 周{} 下班考勤未打卡！", empPo.getName(), dateTemp, weekDay);
        }
        if (!pmFlag) {
            //查询打卡失败记录
            event.setStatus(0);
            eventList = daoService.selectList("selectListByEventTime", event);
            if (CollectionUtils.isNotEmpty(eventList)) {
                pmFlag = false;
                addFlag = true;
                errorType = 5;
                errorMsg = "下班考勤打卡失败！";
                logger.error("{} {} 周{} 下班考勤打卡失败！", empPo.getName(), dateTemp, weekDay);
            }
        }
        if (!(amFlag || pmFlag)) {
            addFlag = true;
            event.setQueryBeginDate(amDate);
            event.setStatus(1);
            eventList = daoService.selectList("selectListByEventTime", event);
            if (CollectionUtils.isNotEmpty(eventList)) {
                errorType = 2;
                errorMsg = "上班未打卡！";
                logger.error("{} {} 周{} 上班未打卡！", empPo.getName(), dateTemp, weekDay);
            } else {
                errorType = 3;
                errorMsg = "缺勤一天！";
                logger.error("{} {} 周{} 缺勤一天！", empPo.getName(), dateTemp, weekDay);
            }
        }
        if (addFlag) {
            ErrorListPo errorPo = new ErrorListPo();
            errorPo.setName(empPo.getName());
            errorPo.setPacteraNo(empPo.getPacteraNo());
            errorPo.setErrorDate(calendar.getTime());
            errorPo.setErrorWeek(weekDay);
            errorPo.setErrorType(errorType);
            errorPo.setErrorMsg(errorMsg);
            errService.save(errorPo);
        }
    }


}
